package com.ruoyi.system.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.system.domain.LabAllPurposeExperiment;
import com.ruoyi.system.domain.LabCementCompressive;
import com.ruoyi.system.domain.LabCompressiveFlexural;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.OutLabService;
import com.ruoyi.system.vo.LabResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.ruoyi.system.utils.XxUtils.getSectionLabList;

/**
 * 实验记录服务
 *
 * @Author LiBingyan
 * @Date 2022/3/20 17:13
 * @Version 1.0
 **/
@Service
@DataSource(value = DataSourceType.SLAVE1)
public class OutLabServiceImpl implements OutLabService {


    @Autowired
    LabAllPurposeExperimentDataMapper labAllPurposeExperimentDataMapper;
    @Autowired
    LabAllPurposeExperimentMapper labAllPurposeExperimentMapper;
    @Autowired
    LabCementCompressiveDataMapper labCementCompressiveDataMapper;
    @Autowired
    LabCementCompressiveMapper labCementCompressiveMapper;
    @Autowired
    LabCompressiveFlexuralDataMapper labCompressiveFlexuralDataMapper;
    @Autowired
    LabCompressiveFlexuralMapper labCompressiveFlexuralMapper;

    /**
     * 页面数据内容轮播，取值为3张表中的值（3个实验类型：抗压、万能、抗折抗压），
     * 数据时间维度（逐日），若当日未做试验，则显示上一天日期内容
     *
     * @param sectionName
     * @param dateStr
     * @return
     */
    @Override
    public List<LabResponse> getNewLabInfo(String sectionName, String dateStr) {
        LambdaQueryWrapper<LabAllPurposeExperiment>
                labAllPurposeExperimentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<LabCementCompressive>
                labCementCompressiveLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<LabCompressiveFlexural>
                labCompressiveFlexuralLambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<String> sectionLabList = getSectionLabList(sectionName);
        labAllPurposeExperimentLambdaQueryWrapper.in(LabAllPurposeExperiment::getDeviceSn, sectionLabList).last("ORDER BY discharge_time DESC LIMIT 1");
        labCementCompressiveLambdaQueryWrapper.in(LabCementCompressive::getDeviceSn, sectionLabList).last("ORDER BY discharge_time DESC LIMIT 1");
        labCompressiveFlexuralLambdaQueryWrapper.in(LabCompressiveFlexural::getDeviceSn, sectionLabList).last("ORDER BY discharge_time DESC LIMIT 1");
        LabAllPurposeExperiment labAllPurposeExperiment = labAllPurposeExperimentMapper.selectOne(labAllPurposeExperimentLambdaQueryWrapper);
        LabCementCompressive labCementCompressive = labCementCompressiveMapper.selectOne(labCementCompressiveLambdaQueryWrapper);
        LabCompressiveFlexural labCompressiveFlexural = labCompressiveFlexuralMapper.selectOne(labCompressiveFlexuralLambdaQueryWrapper);
        Date labAllPurposeExperimentDischargeTime = labAllPurposeExperiment != null ? labAllPurposeExperiment.getDischargeTime() : DateUtil.parse("2012-01-20 18:15:41");
        Date labCementCompressiveDischargeTime = labCementCompressive != null ? labCementCompressive.getDischargeTime() : DateUtil.parse("2012-01-20 18:15:41");
        String dischargeTime = labCompressiveFlexural != null ? labCompressiveFlexural.getDischargeTime() : "2012-01-20 18:15:41";
        Date labCompressiveFlexuralDischargeTime = DateUtil.parse(Optional.ofNullable(dischargeTime).orElse("2012-01-20 18:15:41"));
        Date maxTime = getMaxTime(labAllPurposeExperimentDischargeTime, labCementCompressiveDischargeTime, labCompressiveFlexuralDischargeTime);
        Date maxTimeBegin = DateUtil.beginOfDay(maxTime);
        DateTime start = DateUtil.offsetDay(maxTimeBegin, -7);
        if (!Objects.equals(dateStr, null)) {
            DateTime parse = DateUtil.parse(dateStr, "yyyy/MM/dd");
            DateTime newDate2 = DateUtil.offsetDay(parse, -7);
            start = DateUtil.beginOfDay(newDate2);
        }
        String maxTimeBeginStr = DateUtil.formatDateTime(start);
        labAllPurposeExperimentLambdaQueryWrapper.clear();
        labCementCompressiveLambdaQueryWrapper.clear();
        labCompressiveFlexuralLambdaQueryWrapper.clear();
        labAllPurposeExperimentLambdaQueryWrapper.in(LabAllPurposeExperiment::getDeviceSn, sectionLabList).ge(LabAllPurposeExperiment::getDischargeTime, maxTimeBeginStr);
        labCementCompressiveLambdaQueryWrapper.in(LabCementCompressive::getDeviceSn, sectionLabList).ge(LabCementCompressive::getDischargeTime, maxTimeBeginStr);
        labCompressiveFlexuralLambdaQueryWrapper.in(LabCompressiveFlexural::getDeviceSn, sectionLabList).ge(LabCompressiveFlexural::getDischargeTime, maxTimeBeginStr);
        List<LabAllPurposeExperiment> labAllPurposeExperiments = labAllPurposeExperimentMapper.selectList(labAllPurposeExperimentLambdaQueryWrapper);
        List<LabCementCompressive> labCementCompressives = labCementCompressiveMapper.selectList(labCementCompressiveLambdaQueryWrapper);
        List<LabCompressiveFlexural> labCompressiveFlexurals = labCompressiveFlexuralMapper.selectList(labCompressiveFlexuralLambdaQueryWrapper);
        List<LabResponse> responseList = new ArrayList<>();
        for (LabAllPurposeExperiment allPurposeExperiment : labAllPurposeExperiments) {
            LabResponse labResponse = new LabResponse();
            labResponse.setDischargeTime(allPurposeExperiment.getDischargeTime());
            labResponse.setTestCode(allPurposeExperiment.getTestCode());
            labResponse.setDeviceName(allPurposeExperiment.getDeviceName());
            labResponse.setTestType(allPurposeExperiment.getTestType());
            labResponse.setTestResult(getResult(allPurposeExperiment.getTestResult()));
            responseList.add(labResponse);
        }
        for (LabCementCompressive cementCompressive : labCementCompressives) {
            LabResponse labResponse = new LabResponse();
            labResponse.setDischargeTime(cementCompressive.getDischargeTime());
            labResponse.setTestCode(cementCompressive.getTestCode());
            labResponse.setDeviceName(cementCompressive.getDeviceName());
            labResponse.setTestType(cementCompressive.getTestType());
            labResponse.setTestResult(getResult(cementCompressive.getTestResult()));
            responseList.add(labResponse);
        }
        for (LabCompressiveFlexural compressiveFlexural : labCompressiveFlexurals) {
            LabResponse labResponse = new LabResponse();
            labResponse.setDischargeTime(DateUtil.parse(compressiveFlexural.getDischargeTime()));
            labResponse.setTestCode(compressiveFlexural.getTestCode());
            labResponse.setDeviceName(compressiveFlexural.getDeviceName());
            labResponse.setTestType(compressiveFlexural.getTestType());
            labResponse.setTestResult(getResult(compressiveFlexural.getTestResult()));
            responseList.add(labResponse);
        }
        responseList.sort(Comparator.comparing(LabResponse::getDischargeTime));
        Collections.reverse(responseList);
        return responseList;
    }


    /**
     * 返回实验结果
     *
     * @param integer
     * @return
     */
    private String getResult(Integer integer) {
        if (Objects.equals(integer, 0)) {
            return "合格";
        } else {
            return "不合格";
        }
    }

    /**
     * 返回3个时间内最大的
     *
     * @param a
     * @param b
     * @param c
     * @return
     */
    private Date getMaxTime(Date a, Date b, Date c) {
        Date max = null;
        if (Objects.equals(a, null)) {
            a = DateUtil.parse("2012-01-20 18:15:41");
        }
        if (Objects.equals(b, null)) {
            b = DateUtil.parse("2012-01-20 18:15:41");
        }
        if (a.after(b)) {
            max = a;
        } else {
            max = b;
        }
        if (!max.after(c)) {
            max = c;
        }
        return max;
    }
}
